package com.erp.freight.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.freight.domain.ErpKjxOrderInfo;
import com.erp.freight.domain.KjxStoreAccount;
import com.erp.freight.domain.kjx.*;
import com.erp.freight.mapper.ErpKjxOrderInfoMapper;
import com.erp.freight.service.IKjxStoreAccountService;
import com.erp.freight.service.KjxLogisticsService;
import com.fpx.api.utils.MD5Util;
import com.ruoyi.ae.api.RemoteAeOrderAddrService;
import com.ruoyi.ae.api.RemoteAeOrderService;
import com.ruoyi.ae.api.domain.AeStoreOrderReceiptAddress;
import com.ruoyi.ae.api.domain.AeWarehouseOrderInfo;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.gather.api.RemoteCollectProductService;
import com.ruoyi.gather.api.RemoteCollectProductSkuService;
import com.ruoyi.gather.api.domain.ErpCollectProductSku;
import com.ruoyi.order.api.RemoteErpChildOrderService;
import com.ruoyi.order.api.domain.ErpSellerChildOrder;
import com.ruoyi.order.api.domain.ErpSellerChildOrderExtend;
import com.ruoyi.system.api.RemoteCountryCodeService;
import com.ruoyi.system.api.RemoteDictDataService;
import com.ruoyi.system.api.RemoteSysConfigService;
import com.ruoyi.system.api.domain.CountryTwoCode;
import com.ruoyi.system.api.domain.SysDictData;
import lombok.RequiredArgsConstructor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;


@RequiredArgsConstructor
@Service
public class KjxLogisticsServiceImpl implements KjxLogisticsService {
    private static final String appSecret = "ylI5ARlu5uOHazfOlhlUjz3pSQDeOXoFf1bHDMKuVAU";
    private static final String prefix = "https://openapi-v3.shopeex.cn";
    private final ErpKjxOrderInfoMapper kjxOrderInfoMapper;
    private final IKjxStoreAccountService kjxStoreAccountService;
    private final RemoteAeOrderService remoteAeOrderService;
    private final RemoteAeOrderAddrService remoteAeOrderAddrService;
    private final RemoteDictDataService remoteDictDataService;
    private final RemoteCountryCodeService remoteCountryCodeService;
    private final RemoteErpChildOrderService remoteErpChildOrderService;
    private final RemoteCollectProductSkuService remoteCollectProductSkuService;
    private final RemoteCollectProductService remoteCollectProductService;
    private final RemoteSysConfigService remoteSysConfigService;
    
    @Override
    public String submitOrderAndPack(Long orderId) {

        AeWarehouseOrderInfo aeWarehouseOrderInfo = remoteAeOrderService.getOnlineLogisticsLabel(orderId);
        String onlineLogisticsLabel = aeWarehouseOrderInfo.getOnlineLogisticsLabel();
        // 上传物流面单
        String pdfUrl = uploadbase64(onlineLogisticsLabel);
        if (pdfUrl == null) {
            throw new RuntimeException("物流面单上传失败");
        }
        KjxRequestBody kjxRequestBody = new KjxRequestBody();
        kjxRequestBody.setOrderSn(orderId.toString());
        kjxRequestBody.setTrackingNo(aeWarehouseOrderInfo.getIntlTrackingNo());
        kjxRequestBody.setKjxPlatformId(8);
        kjxRequestBody.setIsCb(1);
        // 根据国家二字码查询对应的熊迪id
        AeStoreOrderReceiptAddress address = remoteAeOrderAddrService.getAddressByOrderId(orderId);
        String country = address.getCountry();
        R<String> serviceDictLabel = remoteDictDataService.getDictLabel("ae_country_code", country, SecurityConstants.INNER);
        SysDictData dictData = JSONObject.parseObject(JSONObject.toJSONString(serviceDictLabel.getData()), SysDictData.class);
        if (dictData != null) {
            country = dictData.getDictLabel();
        }
        CountryTwoCode countryTwoCode = remoteCountryCodeService.getCountryByCode(country);
        if (countryTwoCode == null || countryTwoCode.getKjxCountryId() == null) {
            kjxRequestBody.setKjxCountryId(1); // 全球
        }else {
            kjxRequestBody.setKjxCountryId(countryTwoCode.getKjxCountryId()); // 国家Id
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        kjxRequestBody.setShipTime(calendar.getTime().getTime());
        kjxRequestBody.setCancelTime(calendar.getTime().getTime());
        kjxRequestBody.setDaysToShip(7);
        kjxRequestBody.setCod(0);
        kjxRequestBody.setAirwayBillUrl(pdfUrl);
        KjxOrderItems kjxOrderItems = null;
        List<KjxOrderItems> orderItemsList = new ArrayList<>();
        List<ErpSellerChildOrder> childOrderList = remoteErpChildOrderService.getChildByOrder(orderId);
        String skuImage = "";
        for (ErpSellerChildOrder childOrder : childOrderList) {
            kjxOrderItems = new KjxOrderItems();
            String childOrderId = childOrder.getChildOrderId();
            String skuCode = childOrder.getSkuCode();
            ErpSellerChildOrderExtend childOrderExtend = remoteErpChildOrderService.getChildExtendByChildOrder(childOrderId);
            String kjxProductName = childOrderExtend.getKjxProductName();
            if(StringUtils.isEmpty(kjxProductName)) {
                ErpCollectProductSku skuInfo = remoteCollectProductSkuService.getSkuInfoBySkuCode(skuCode);
                Long collectProductId = skuInfo.getCollectProductId();
                skuImage = skuInfo.getSkuImage();
                // 获取商品规格
                Map<String, Object> categoryMap = remoteCollectProductService.getCategoryByCollectId(collectProductId);
                String categoryCN = (String) categoryMap.get("categoryCN");
                R<Object> specBySkuCdeNew = remoteCollectProductSkuService.getSpecBySkuCodeNew(skuCode);
                String specBySkuCde = JSONObject.toJSONString(specBySkuCdeNew.getData());
                if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(specBySkuCde)) {
                    String temp = "";
                    temp = categoryCN + " " + specBySkuCde;
                    if (temp.length() < 100) {
                        categoryCN = temp;
                    }
                }
                kjxOrderItems.setItemName(categoryCN);
            }else {
                kjxOrderItems.setItemName(kjxProductName);
            }
            Long productCount = childOrder.getProductCount();
            kjxOrderItems.setVariationQuantityPurchased(productCount.intValue());
            if (skuImage != null) {
                if (!skuImage.contains("http")) {
                    skuImage = "https://file.pbb2c.com/" + skuImage;
                }
                kjxOrderItems.setSkuImages(skuImage);
            }
            BatchItemLogisticsDTOs batchItemLogisticsDTOs = new BatchItemLogisticsDTOs();
            // 如果是仓储发货，国内运单号变为库存kc码
            batchItemLogisticsDTOs.setLogisticsNo(childOrderExtend.getCnTrackingNo());

            List<BatchItemLogisticsDTOs> logisticsDTOsList = new ArrayList<>();
            logisticsDTOsList.add(batchItemLogisticsDTOs);
            kjxOrderItems.setBatchItemLogisticsDTOs(logisticsDTOsList);
            orderItemsList.add(kjxOrderItems);
        }
        kjxRequestBody.setKjxOrderItems(orderItemsList);
        KjxPackageDespDTO kjxPackageDespDTO = new KjxPackageDespDTO();

        kjxPackageDespDTO.setPackageDesp("请核对颜色，重量 ，尺寸及数量（包装重量不超2kg ,尺寸单边不超60 ，三边不超90）");
        kjxPackageDespDTO.setPackageImageList(new ArrayList<>());
        kjxRequestBody.setKjxPackageDespDTO(kjxPackageDespDTO);

        KjxOrderPackageDTO kjxOrderPackageDTO = new KjxOrderPackageDTO();
        kjxOrderPackageDTO.setKjxStoreChargeIdList(new ArrayList<>());
        kjxOrderPackageDTO.setPackageIsGrantScore(0);

        // 获取仓库Id
        String additionalServiceList = rechargeAndAdditionalServiceList(null);
        JSONObject additionalListJson = JSONObject.parseObject(additionalServiceList);
        if (additionalListJson.getInteger("code") != 1000) {
            throw new RuntimeException("获取仓库id失败");
        }
        Integer storeAddressId = additionalListJson.getJSONArray("data")
                .getJSONObject(0).getInteger("storeAddressId");
        kjxOrderPackageDTO.setStoreAddressId(storeAddressId);

//        kjxOrderPackageDTO.setTotalScore(0);
        kjxRequestBody.setKjxOrderPackageDTO(kjxOrderPackageDTO);
        SenderAddress senderAddress = new SenderAddress();
        kjxRequestBody.setSenderAddress(senderAddress);
        Map<String, Object> map = BeanUtil.beanToMap(kjxRequestBody, new HashMap<>(), false, false);
        String post = kjxPost("/api/batch/add", map, null);
        JSONObject jsonObject = JSONObject.parseObject(post);
        Integer code = jsonObject.getInteger("code");
        String kjxOrderIds = null;
        if (code == 1000) {
            kjxOrderIds = jsonObject.getJSONObject("data").getString("kjxOrderIds");
            // 将kjxOrderIds保存，用于查询状态
            ErpKjxOrderInfo erpKjxOrderInfo = kjxOrderInfoMapper.selectOne(new LambdaQueryWrapper<ErpKjxOrderInfo>().eq(ErpKjxOrderInfo::getOrderId, orderId));
            if (erpKjxOrderInfo == null) {
                erpKjxOrderInfo = new ErpKjxOrderInfo();
            }
            erpKjxOrderInfo.setOrderId(orderId.toString());
            erpKjxOrderInfo.setKjxOrderIds(kjxOrderIds);
            erpKjxOrderInfo.setStatus(0);
            kjxOrderInfoMapper.insertOrUpdate(erpKjxOrderInfo);
        } else {
            throw new RuntimeException("发货失败：" + jsonObject.getString("message"));
        }
        return kjxOrderIds;
    }

    @Override
    public String getOrderDetail(Map<String, Object> idss) {
        return kjxPost("/api/order/orderList", idss, null);
    }

    /**
     * 上传pdf面单接口
     */
    private String uploadbase64(String base64Content) {
        String url = "/api/upload/uploadbase64/pdf";
        Map<String, Object> uploadPdf = new HashMap<>();
        uploadPdf.put("base64Content", base64Content);
        String pdfResponse = kjxPost("/api/upload/uploadbase64/pdf", uploadPdf, null);
        JSONObject pdfResponseJson = JSONObject.parseObject(pdfResponse);
        Integer pdfCode = pdfResponseJson.getInteger("code");
        if (pdfCode == 1000) {
            return pdfResponseJson.getJSONObject("data").getString("fileUrl");
        }
        System.out.println("上传失败原因：" + pdfResponseJson.getString("message"));
        return null;
    }

    // 获取签名
    private static String getSignature(String requestBody) {
        String str = requestBody + appSecret;
        String md5 = MD5Util.doMd5(str).toLowerCase();
        return Base64Utils.encodeToString(md5.getBytes());
    }

    // 获取openId
    public String getKjxOpenId(String account) {
        Map<String, Object> map = new HashMap<>();
        if (account == null) {
            R<Object> configKey = remoteSysConfigService.getConfigKey("kjx_user_info");
            if (configKey.getCode() != 200) {
                throw new RuntimeException(configKey.getMsg());
            }
            String msg = configKey.getMsg();
            map = new HashMap<>(JSONObject.parseObject(msg));
        }else {
            // 根据账号获取账号信息
            KjxStoreAccount accountInfo = kjxStoreAccountService.getInfoByAccount(account);
            if (accountInfo != null) {
                map.put("username", accountInfo.getUsername());
                map.put("password", accountInfo.getPassword());
                map.put("accessUrl", accountInfo.getAccessUrl());
            }else {
                return null;
            }
        }

        String url = prefix + "/api/kjxUser/authLogin";
        KjxBase kjxBase = new KjxBase();
        kjxBase.setSign(getSignature(new JSONObject(map).toString()));
        kjxBase.setRequestBody(map);

        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
        ResponseEntity<String> exchange = restTemplate.postForEntity(url, kjxBase, String.class);
        JSONObject authLoginJson = JSONObject.parseObject(exchange.getBody());
        Integer authCode = authLoginJson.getInteger("code");
        if (authCode != 1000) {
            throw new RuntimeException(authLoginJson.getString("message"));
        }
        JSONObject authData = authLoginJson.getJSONObject("data");
        return authData.getString("openId");
    }

    // 请求
    private String kjxPost(String url, Map<String,Object> map,String account)  {
        url = prefix + url;
        KjxBase kjxBase = new KjxBase();
        kjxBase.setSign(getSignature(new JSONObject(map).toString()));
        kjxBase.setRequestBody(map);
        String kjxOpenId = getKjxOpenId(account);
        OkHttpClient client = new OkHttpClient();
        okhttp3.RequestBody body = okhttp3.RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                JSONObject.toJSONString(kjxBase)); // 替换为你的POST请求体
        Request request = new Request.Builder()
                .url(url)
                .header("openId", kjxOpenId) // 设置OpenID请求头
                .post(body)
                .build();
        Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        try {
            return response.body().string();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取仓库地址列表
     * @return 列表
     */
    public String rechargeAndAdditionalServiceList(String account) {
        String url = "/api/kjxStoreAddress/list";
        Map<String, Object> map = new HashMap<>();
        return kjxPost(url, map, account);
    }

    @Override
    public void inventoryRequest(InventoryRequest request) {
        RestTemplate restTemplate = new RestTemplate();
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(request);
        System.out.println(jsonObject);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity("http://47.94.131.193:8000/junjie/stock", jsonObject, JSONObject.class);
        JSONObject body = responseEntity.getBody();
        if (body.getInteger("code") != 200 ) {
            throw new RuntimeException(body.getString("msg"));
        }
        JSONObject data = body.getJSONObject("data");
        Integer code = data.getInteger("code");
        if (code != 1000) {
            throw new RuntimeException(data.getString("message"));
        }
    }

    @Override
    public void replenishment(KjxReplenishment replenishment) {
        RestTemplate restTemplate = new RestTemplate();
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(replenishment);
        System.out.println(jsonObject);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity("http://47.94.131.193:8000/junjie/bucang", jsonObject, JSONObject.class);
        JSONObject body = responseEntity.getBody();
        if (body.getInteger("code") != 200 ) {
            throw new RuntimeException(body.getString("msg"));
        }
        JSONObject data = body.getJSONObject("data");
        Integer code = data.getInteger("code");
        if (code != 1000) {
            throw new RuntimeException(data.getString("message"));
        }
        System.out.println(body);
    }

    /**
     * 获取用户库存
     */
    public Page<KjxStockProduct> storeProductList(KjxStoreQueryParam param) {
        Map<String, Object> map = new HashMap<>();
        if (param.getArrivedStore() != null) {
            map.put("arrivedStore",param.getArrivedStore());
        }
        if (param.getTrackingNumber() != null) {
            map.put("trackingNumber", param.getTrackingNumber());
        }
        if (param.getStatus() != null) {
            map.put("status", param.getStatus());
        }
        if (param.getAnotherName() != null) {
            map.put("anotherName", param.getAnotherName());
        }
        Integer stockPlusDeliveryId = param.getStockPlusDeliveryId();
        if (stockPlusDeliveryId != null) {
            map.put("stockPlusDeliveryId", stockPlusDeliveryId);
        }else {
            map.put("stockPlusDeliveryId", "");
        }
        map.put("pageNumber", param.getPageNumber());
        map.put("pageSize", param.getPageSize());
        String post = kjxPost("/api/kjxStock/list", map, param.getAccount());
        JSONObject jsonObject = JSONObject.parseObject(post);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONArray list = data.getJSONArray("list");
        KjxStockProduct stockProduct = null;
        List<KjxStockProduct> stockProductList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            stockProduct = new KjxStockProduct();
            JSONObject listJSONObject = list.getJSONObject(i);
            {
                Integer stockPlusId = listJSONObject.getInteger("stockPlusId");
                stockProduct.setStockPlusId(stockPlusId);
                String desp = listJSONObject.getString("desp");
                stockProduct.setDesp(desp);
                String arrivedStore = listJSONObject.getString("arrivedStore");
                stockProduct.setArrivedStore(arrivedStore);
                Integer status = listJSONObject.getInteger("status");
                stockProduct.setStatus(status);
                Integer trackingAmount = listJSONObject.getInteger("trackingAmount");
                stockProduct.setTrackingAmount(trackingAmount);
                String itemNo = listJSONObject.getString("itemNo");
                stockProduct.setItemNo(itemNo);
                String stockName = listJSONObject.getString("stockName");
                stockProduct.setStockName(stockName);
                String skuImage = listJSONObject.getString("skuImage");
                stockProduct.setSkuImage(skuImage);
                String trackingNumber = listJSONObject.getString("trackingNumber");
                stockProduct.setTrackingNumber(trackingNumber);
                String stockAreaCodeTitle = listJSONObject.getString("stockAreaCodeTitle");
                stockProduct.setStockAreaCodeTitle(stockAreaCodeTitle);
                String stockGoodsCodeTitle = listJSONObject.getString("stockGoodsCodeTitle");
                stockProduct.setStockGoodsCodeTitle(stockGoodsCodeTitle);
                String locationNo = listJSONObject.getString("locationNo");
                stockProduct.setLocationNo(locationNo);
                String anotherName = listJSONObject.getString("anotherName");
                stockProduct.setAnotherName(anotherName);
                String trackNo = listJSONObject.getString("trackNo");
                stockProduct.setTrackNo(trackNo);
                Integer cpfrAmount = listJSONObject.getInteger("cpfrAmount");
                stockProduct.setCpfrAmount(cpfrAmount);
                Integer cpfrType = listJSONObject.getInteger("cpfrType");
                stockProduct.setCpfrType(cpfrType);
            }
            {
                JSONObject kjxStoreAddress = listJSONObject.getJSONObject("kjxStoreAddress");
                Integer storeId = kjxStoreAddress.getInteger("storeId");
                stockProduct.setStoreId(storeId);
                String storeName = kjxStoreAddress.getString("storeName");
                stockProduct.setStoreName(storeName);
                stockProductList.add(stockProduct);
            }
        }
        Page<KjxStockProduct> page = new Page<>();
        page.setRecords(stockProductList);
        Long total = data.getLong("total");
        page.setTotal(total);
        return page;
    }

    public String getKjxStoreInfo() {
        Map<String, Object> map = new HashMap<>();
        return kjxPost("/api/kjxStoreInfo/list", map, null);
    }

}
